package com.mj.controller;

import java.io.BufferedOutputStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.demo.trade.config.Configs;
import com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderResult;
import com.mj.common.Constants;
import com.mj.controller.common.QRUtil;
import com.mj.req.BaseResp;
import com.mj.trade.api.alipay.AliPayService;
import com.mj.trade.entity.Product;
import com.mj.util.ErrCode;
import com.mj.util.RedisUtil;
import com.mj.util.StringUtil;

/**
 * 支付宝二维码支付
 */
@Controller
@RequestMapping(value = "alipay")
public class AliPayController {
	private static final Logger logger = LoggerFactory.getLogger(AliPayController.class);
	@Autowired
	private AliPayService aliPayService;
	
	@RequestMapping(value="/pcPay",method=RequestMethod.POST)
	@ResponseBody
	public BaseResp<String> pcPay() {
		Product product = new Product();
		product.setOutTradeNo(StringUtil.get32UUID());
		product.setSubject("测试");
		product.setTotalFee("1");
		String aliPayPc = aliPayService.aliPayPc(product);
		//创建失败
		if(Constants.FAIL.equals(aliPayPc)) {
			return new BaseResp<>(ErrCode.FAILED,"fail");
		}
		return new BaseResp<>(ErrCode.SUCCESS,"success",aliPayPc);
	}
	
	/**
	 * 二维码支付
	 * 返回二维码地址
	 * @param product
	 * @param map
	 * @return
	 */
	@RequestMapping(value="/qcPay",method=RequestMethod.POST)
	@ResponseBody
//	public BaseResp<String> qcPay(@RequestBody Product product) {
	public BaseResp<String> qcPay() {
		Product product = new Product();
		product.setOutTradeNo(StringUtil.get32UUID());
		product.setSubject("测试");
		product.setTotalFee("1");
		logger.info("二维码支付");
		String message = aliPayService.aliPay(product);
		if (Constants.SUCCESS.equals(message)) {
			//从redis取出二维码以后移除
			String QRCord = RedisUtil.get(product.getOutTradeNo());
			RedisUtil.remove(product.getOutTradeNo());
			return new BaseResp<>(ErrCode.SUCCESS,"success",QRCord);
		} else {
			return new BaseResp<>(ErrCode.FAILED,"fail");
		}
	}
	
	/**
	 * 生成二维码图片并直接以流的形式输出到页面
	 * 
	 * @param code_url
	 * @param response
	 */
	@RequestMapping("qr_code.img")
	@ResponseBody
	public void getQRCode(String code_url, HttpServletResponse response) {
		QRUtil.encodeQrcode(code_url, response);
	}
	
	/**
	 * 支付宝支付回调(二维码、H5、网站)
	 * @param request
	 * @param response
	 * @throws Exception
	 *             void
	 *
	 */
	@RequestMapping(value = "payCallBack", method = RequestMethod.POST)
	public void alipay_notify(HttpServletRequest request, HttpServletResponse response) throws Exception {
		String message = "success";
		Map<String, String> params = new HashMap<String, String>();
		// 取出所有参数是为了验证签名
		Enumeration<String> parameterNames = request.getParameterNames();
		while (parameterNames.hasMoreElements()) {
			String parameterName = parameterNames.nextElement();
			params.put(parameterName, request.getParameter(parameterName));
		}
		// 验证签名 校验签名
		boolean signVerified = false;
		try {
			signVerified = AlipaySignature.rsaCheckV1(params, Configs.getAlipayPublicKey(), "UTF-8");
		} catch (AlipayApiException e) {
			logger.error("签名验证失败：{}",e.getMessage());
			message = "failed";
		}
		if (signVerified) {
			logger.info("支付宝验证签名成功！");
			// 若参数中的appid和填入的appid不相同，则为异常通知
			if (!Configs.getAppid().equals(params.get("app_id"))) {
				logger.info("与付款时的appid不同，此为异常通知，应忽略！");
				message = "failed";
			} else {
				String outtradeno = params.get("out_trade_no");
				// 在数据库中查找订单号对应的订单，并将其金额与数据库中的金额对比，若对不上，也为异常通知
				String status = params.get("trade_status");
				if (status.equals("WAIT_BUYER_PAY")) { // 如果状态是正在等待用户付款
					logger.info(outtradeno + "订单的状态正在等待用户付款");
					message = "订单正在等待用户付款";
				} else if (status.equals("TRADE_CLOSED")) { // 如果状态是未付款交易超时关闭，或支付完成后全额退款
					logger.info(outtradeno + "订单的状态已经关闭");
					message = "订单已经关闭";
				} else if (status.equals("TRADE_SUCCESS") || status.equals("TRADE_FINISHED")) { // 如果状态是已经支付成功
					logger.info("(支付宝订单号:" + outtradeno + "付款成功)");
					// 这里 根据实际业务场景 做相应的操作
				} else {

				}
			}
		} else { // 如果验证签名没有通过
			message = "failed";
			logger.info("验证签名失败！");
		}
		BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
		out.write(message.getBytes());
		out.flush();
		out.close();
	}

	/**
	 * 保存订单修改redis状态
	 * 
	 * @param kvm
	 * @param orderResult
	 */
	// private void saveOrderAndNotify(Map<String, String> kvm, WxPayOrderResult
	// orderResult, String state) {
	// // 获取预支付订单
	// String string = RedisUtil.get("WxPayOrder:" + kvm.get("out_trade_no"));
	// WxPayUnifiedOrder order = JSON.parseObject(string, WxPayUnifiedOrder.class);
	// orderResult.setShopId(order.getShopId());
	// int createTradeRecord = tradeService.createTradeRecord(orderResult);
	// // 完成以后修改redis状态
	// if (createTradeRecord > 0) {
	// // 通知前端页面，移除微信订单
	// WebsocketController.broadcast(orderResult.getOutTradeNo(), state);
	// RedisUtil.remove("WxPayOrder:" + kvm.get("out_trade_no"));
	// }
	// }
}
